package com.ljl.basic.service.impl;

import com.ljl.basic.exception.BusinessException;
import com.ljl.basic.service.IVerifyCodeSerive;
import com.ljl.basic.util.SmsUtil;
import com.ljl.basic.util.StrUtils;
import com.ljl.basic.util.VerifyCodeUtils;
import com.ljl.org.dto.SmsCodeDto;
import com.ljl.user.domain.User;
import com.ljl.user.mapper.UserMapper;
import org.apache.ibatis.builder.BuilderException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeSeriveImpl implements IVerifyCodeSerive {


    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private UserMapper userMapper;
    @Override
    public String getImageCode(String key) {
        // 判断是否接收到了key
        if (key== null){
            throw  new BuilderException("获取key失败");
        }
        // 随机生成图形验证码
        String code = StrUtils.getComplexRandomString(4);
        // 将图形验证码存入redis中，并设置5分钟过期
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        // 将code转换成64位的编码，并返回
        String base64Str = VerifyCodeUtils.verifyCode(115, 42, code);
        return base64Str;
    }

    @Override
    public void sendSmsCode(SmsCodeDto smsCodeDto) {
        String phone = smsCodeDto.getPhone();
        String sendImageCode = smsCodeDto.getImageCode();
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        //1.校验 - 空值校验
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("请输入电话号码");
        }
        if(StringUtils.isEmpty(sendImageCode)){
            throw new BusinessException("请输入图形验证码");
        }
        if(StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("请重新获取图形验证码");
        }
        //2.校验 - 图片验证码校验
        //2.1.图片验证码是否过期
        Object redisImageCode = redisTemplate.opsForValue().get(imageCodeKey);

        if (redisImageCode == null){
            throw new BusinessException("图形验证码过期");
        }
        //2.2.图片验证码是否正确
        if(!sendImageCode.equalsIgnoreCase(redisImageCode.toString())){
            throw new BusinessException("图形验证码输入错误");
        }

        //3.校验 - 手机号是否被注册 - 查询t_user表
        User user = userMapper.findByPhone(phone);
        if(user != null){
            throw new BusinessException("此号码已经注册，如果忘记密码，请联系管理员");
        }
        //4.判断原来的验证码是否有效【3分钟过期 - redis】，从redis是否能拿到通过key【register:18708146200】
        Object redisSmsCode = redisTemplate.opsForValue().get("register:" + phone);
        String code = null;
        if (redisSmsCode == null){
            code = StrUtils.getComplexRandomString(6);
        }else {
            //4.1.如果拿到了，表示有效,继续判断是否过了1分钟重发时间 value【9527:14688777777711】
           long redisTime =  Long.parseLong(redisSmsCode.toString().split(":")[1]);

           long nowTime = System.currentTimeMillis();
            //4.1.1.如果没有过，就不应该再发，提示错误 - 请勿重发验证码
           if((nowTime-redisTime)<1*60*1000){
               throw new BusinessException("请勿重复获取验证码");
           }
           //4.1.2.如果过了，就使用上次的验证码，但是要刷新过期时间【重新添加resis，用新的时间戳】
            code = redisSmsCode.toString().split(":")[0];
        }

        //4.2.如果没有拿到，表示验证码过期了
        //4.2.1.重新生成验证码，并添加到redis
        redisTemplate.opsForValue().set("register:" + phone,code + ":" + System.currentTimeMillis(),
                3,TimeUnit.MINUTES);
        //5.调用短信接口发送短信
        // SmsUtil.sendSms(phone,"你的验证码是"+ code +"请在三分钟内输入");
        System.out.println("你的验证码是"+ code +"请在三分钟内输入");
    }

    @Override
    public void binderSmsCode(SmsCodeDto smsCodeDto) {
        String phone = smsCodeDto.getPhone();
        //1.校验 - 空值校验
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("请输入电话号码");
        }

        //4.判断原来的验证码是否有效【3分钟过期 - redis】，从redis是否能拿到通过key【register:18708146200】
        Object redisSmsCode = redisTemplate.opsForValue().get("binder:" + phone);
        String code = null;
        if (redisSmsCode == null){
            code = StrUtils.getComplexRandomString(6);
        }else {
            //4.1.如果拿到了，表示有效,继续判断是否过了1分钟重发时间 value【9527:14688777777711】
            long redisTime =  Long.parseLong(redisSmsCode.toString().split(":")[1]);

            long nowTime = System.currentTimeMillis();
            //4.1.1.如果没有过，就不应该再发，提示错误 - 请勿重发验证码
            if((nowTime-redisTime)<1*60*1000){
                throw new BusinessException("请勿重复获取验证码");
            }
            //4.1.2.如果过了，就使用上次的验证码，但是要刷新过期时间【重新添加resis，用新的时间戳】
            code = redisSmsCode.toString().split(":")[0];
        }

        //4.2.如果没有拿到，表示验证码过期了
        //4.2.1.重新生成验证码，并添加到redis
        redisTemplate.opsForValue().set("binder:" + phone,code + ":" + System.currentTimeMillis(),
                3,TimeUnit.MINUTES);
        //5.调用短信接口发送短信
        // SmsUtil.sendSms(phone,"你的验证码是"+ code +"请在三分钟内输入");
        System.out.println("你的验证码是"+ code +"请在三分钟内输入");

    }
}
